/**
  ******************************************************************************
  * @file           : ECCOperator.cpp
  * @author         : sally
  * @brief          : None
  * @attention      : None
  * @date           : 24-12-16
  ******************************************************************************
  */

#include "ECCOperator.h"
#include "TimeOperation.h"
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <iostream>
#include <memory>
#include <openssl/bn.h>
#include <openssl/core_names.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include <openssl/obj_mac.h>
#include <openssl/param_build.h>
#include <openssl/params.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/types.h>
#include <ostream>
#include <random>
#include <string>
#include <vector>

unsigned char* generate_salt(size_t length)
{
    // 1.生成随机数种子
    std::random_device rd;
    // 2. 初始化随机数生成器
    std::mt19937 generator(rd());
    std::uniform_int_distribution<> distribution(0, 255);

    unsigned char* salt = (unsigned char*) OPENSSL_malloc(length);
    if (!salt) {
        perror("malloc");
        return nullptr;
    }
    for (size_t i = 0; i < length; ++i) {
        salt[i] = static_cast<unsigned char>(distribution(generator));
    }
    return salt;
}

std::string base64_encode(const unsigned char* data, size_t length)
{
    BIO *bio, *b64;
    BUF_MEM* bufferPtr;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // Do not add newlines
    BIO_write(bio, data, length);
    (void) BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);

    std::string encoded_data(bufferPtr->data, bufferPtr->length);
    BIO_free_all(bio);
    return encoded_data;
}

std::vector<unsigned char> xorData(const std::vector<unsigned char>& data1,
                                   const std::vector<unsigned char>& data2)
{
    size_t length = data1.size();
    std::vector<unsigned char> result(length);

    for (size_t i = 0; i < length; ++i) {
        result[i] = data1[i] ^ data2[i];
    }
    return result;
}

std::vector<unsigned char> padStringWithZeros(const std::vector<unsigned char>& input,
                                              size_t target_length)
{
    std::vector<unsigned char> output = input;
    if (input.size() < target_length) {
        output.insert(output.end(), target_length - input.size(), 0);
    }
    return output;
}

std::vector<unsigned char> concatenate(const std::vector<unsigned char>& a,
                                       const std::vector<unsigned char>& b)
{
    std::vector<unsigned char> result = a; // 复制第一个数组
    result.insert(result.end(), b.begin(), b.end());
    return result;
}

std::vector<unsigned char> concatenate(const std::string& a, const std::string& b)
{
    std::vector<unsigned char> result(a.begin(), a.end());
    std::vector<unsigned char> b_vector(b.begin(), b.end());
    result.insert(result.end(), b.begin(), b.end());
    return result;
}

ECCOperator::ECCOperator()
    : q_(BN_new())
    , n_(BN_new())
    , a_(BN_new())
    , b_(BN_new())
    , P_(EC_POINT_new(nullptr))
    , curveAttributes_(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))
    , XP_(BN_new())
    , YP_(BN_new())
    , h_(BN_new())
    , ctx_(BN_CTX_new())
{
    if (!curveAttributes_) {
        std::cerr << "Error creating EC_GROUP" << std::endl;
        exit(EXIT_FAILURE);
    }

    //获取素数q
    if (!EC_GROUP_get_curve(curveAttributes_, q_, a_, b_, ctx_)) {
        std::cerr << "Error getting curve parameters" << std::endl;
        exit(EXIT_FAILURE);
    }

    //获取子群的阶和协因子h
    if (!EC_GROUP_get_order(curveAttributes_, n_, ctx_)) {
        std::cerr << "Error getting order" << std::endl;
        exit(EXIT_FAILURE);
    }

    if (!EC_GROUP_get_cofactor(curveAttributes_, h_, ctx_)) {
        std::cerr << "Error getting cofactor" << std::endl;
        exit(EXIT_FAILURE);
    }

    // EC_GROUP_get_cofactor( curveAttributes_, h_, ctx_ );

    //创建基点P_
    P_ = EC_POINT_new(curveAttributes_);
    if (!P_) {
        std::cerr << "Error creating EC_POINT" << std::endl;
        exit(EXIT_FAILURE);
    }
    //获取并复制基点
    if (!EC_POINT_copy(P_, EC_GROUP_get0_generator(curveAttributes_))) {
        std::cerr << "Error copying generator point" << std::endl;
        exit(EXIT_FAILURE);
    }

    //获取横纵坐标
    if (!EC_POINT_get_affine_coordinates(curveAttributes_, P_, XP_, YP_, ctx_)) {
        std::cerr << "Error getting affine coordinates" << std::endl;
        exit(EXIT_FAILURE);
    }
}

ECCOperator::~ECCOperator()
{
    BN_free(q_);
    BN_free(n_);

    BN_free(a_);
    BN_free(b_);

    BN_free(XP_);
    BN_free(YP_);
    BN_free(h_);
    EC_GROUP_free(curveAttributes_);
    EC_POINT_free(P_);
    BN_CTX_free(ctx_);
}

std::shared_ptr<BIGNUM> ECCOperator::GeneratePriKey()
{
    //生成私钥
    //生成一个随机数k_priv，这个随机数的范围是(1,n)，n即曲线的阶
    //这样可能跟论文中的不一样，但是这个私钥的值虽然可能为1，但是是及其不安全的，因此当1作为私钥是非常弱的，会导致公钥等于基点，容易被攻击者利用。
    // BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range)
    BIGNUM* k_priv = BN_new();

    BIGNUM* one = BN_new();
    BIGNUM* n_minus_one = BN_new();

    if (!k_priv || !one || !n_minus_one) {
        std::cerr << "Memory allocation failed" << std::endl;
        if (k_priv)
            BN_free(k_priv);
        if (one)
            BN_free(one);
        if (n_minus_one)
            BN_free(n_minus_one);
        return nullptr;
    }

    //设置one的值为1
    BN_set_word(one, 1);
    //减一得到范围

    BN_sub(n_minus_one, n_, one); //大数减法运算
    int attempts = 0;
    const int max_attempts = 10;

    while (true) {
        if (!BN_priv_rand_range(k_priv, n_minus_one)) {
            std::cerr << "Error generating random number" << std::endl;
            BN_free(k_priv);
            BN_free(one);
            BN_free(n_minus_one);
            return nullptr;
        }

        BN_add(k_priv, k_priv, one); // 将范围 [0, n-1) 转换为 [1, n)

        if (BN_cmp(k_priv, one) > 0 && BN_cmp(k_priv, n_) < 0) {
            break; // 私钥在合法范围内，退出循环
        }

        if (++attempts >= max_attempts) {
            std::cerr << "Failed to generate valid private key after " << max_attempts
                      << " attempts" << std::endl;
            BN_free(k_priv);
            BN_free(one);
            BN_free(n_minus_one);
            return nullptr;
        }
    }

    BN_free(one);
    BN_free(n_minus_one);
    return std::shared_ptr<BIGNUM>(k_priv, BnDeleter);
}

std::shared_ptr<EC_POINT> ECCOperator::GeneratePubKey(BIGNUM* PriKey)
{
    //创建公钥并初始化
    EC_POINT* k_pub = EC_POINT_new(curveAttributes_);

    //使用EC_POINT_mul函数来进行椭圆曲线点乘操作。
    /*

    函数原型：int EC_POINT_mul(const EC_GROUP *group,
             EC_POINT *r,
             const BIGNUM *n,
             const EC_POINT *q,
             const BIGNUM *m,
             BN_CTX *ctx);
        group：一个 EC_GROUP 指针，表示椭圆曲线群。
        r：一个 EC_POINT 指针，表示结果点𝑅。
        n：一个 BIGNUM 指针，表示标量𝑘。
        q：一个 EC_POINT 指针，表示点𝑄。
        m：一个 BIGNUM 指针，表示标量𝑙。
        ctx：一个 BN_CTX 指针，用于临时变量的上下文。
        返回值：成功返回1，失败返回0
    */
    if (EC_POINT_mul(curveAttributes_, k_pub, PriKey, nullptr, nullptr, ctx_)) {
        //还需要检查公钥是否是椭圆曲线加法循环群G上的点。
        //使用函数EC_POINT_is_on_curve
        int flag = EC_POINT_is_on_curve(curveAttributes_, k_pub, ctx_);
        if (flag == 1) {
            return std::shared_ptr<EC_POINT>(k_pub, ECPointDeleter);
        } else {
            return nullptr;
        }
    } else {
        return nullptr;
    }
}

std::shared_ptr<unsigned char> ECCOperator::EC_POINT2Char(EC_POINT* point,
                                                          point_conversion_form_t form)
{
    /*
       char *EC_POINT_point2hex(const EC_GROUP *group, const EC_POINT *point,point_conversion_form_t form, BN_CTX
       *ctx); 用于将椭圆曲线上的点（EC_POINT）转换为十六进制字符串表示。 group：一个 EC_GROUP 指针，表示椭圆曲线群。
        point：一个 EC_POINT 指针，表示要转换的椭圆曲线上的点。
        form：一个 point_conversion_form_t 类型，表示点的转换形式。常见的值有：
        POINT_CONVERSION_COMPRESSED：压缩形式。
        POINT_CONVERSION_UNCOMPRESSED：非压缩形式。
        POINT_CONVERSION_HYBRID：混合形式。
        ctx：一个 BN_CTX 指针，用于临时变量的上下文。可以为 nullptr。
        返回值
        成功：返回一个指向以零结尾的字符串的指针，表示点的十六进制表示形式。需要调用 OPENSSL_free
       来释放返回的字符串。 失败：返回 nullptr，表示转换失败。
   */
    unsigned char* Cpoint = (unsigned char*) EC_POINT_point2hex(curveAttributes_, point, form, ctx_);
    if (Cpoint) {
        return std::shared_ptr<unsigned char>(Cpoint, UCharOpenSSlDeleter);
    } else {
        return nullptr;
    }
}

std::string ECCOperator::EC_POINT_To_String(const EC_POINT* point)
{
    char* Cpoint = EC_POINT_point2hex(curveAttributes_, point, POINT_CONVERSION_UNCOMPRESSED, ctx_);
    if (!Cpoint) {
        OPERATION_FAIL("EC_POINT_To_String", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    std::string result(Cpoint);
    OPENSSL_free(Cpoint);
    return result;
}

std::string ECCOperator::ecPointToBinaryString(const EC_POINT* point)
{
    unsigned char* point_buff = nullptr;
    size_t len = EC_POINT_point2buf(curveAttributes_,
                                    point,
                                    POINT_CONVERSION_UNCOMPRESSED,
                                    &point_buff,
                                    ctx_);
    if (len == 0 || !point_buff) {
        OPERATION_FAIL("EC_POINT_point2buf", "PLeaderVehicle", __FILE__, __LINE__, "");
        return "";
    }
    std::string binaryString(reinterpret_cast<const char*>(point_buff), len);
    OPENSSL_free(point_buff);
    return binaryString;
}

EC_POINT* ECCOperator::ecBinaryStringToEcPoint(const std::string& point)
{
    if (point.empty()) {
        OPERATION_FAIL("ecBinaryStringToEcPoint,point is empty",
                       "ECCOperator",
                       __FILE__,
                       __LINE__,
                       "");
        return nullptr;
    }

    EC_POINT* point_ec = EC_POINT_new(curveAttributes_);
    if (!point_ec) {
        OPERATION_FAIL("EC_POINT_new point_ec", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    if (!EC_POINT_is_on_curve(curveAttributes_, point_ec, ctx_)) {
        std::cerr << "Error: Point is not on the curve!" << std::endl;
        EC_POINT_free(point_ec);
        return nullptr;
    }
    std::vector<unsigned char> point_vector(point.begin(), point.end());
    if (!EC_POINT_oct2point(curveAttributes_,
                            point_ec,
                            reinterpret_cast<const unsigned char*>(point.c_str()),
                            static_cast<int>(point.size()),
                            ctx_)) {
        OPERATION_FAIL("convert binary string to EC_POINT", "ECCOperator", __FILE__, __LINE__, "");
        EC_POINT_free(point_ec);
        return nullptr;
    }

    return point_ec;
}

BIGNUM* ECCOperator::bnBinaryStringToBn(const std::string& bn_str)
{
    // std::vector<unsigned char> bn_vector(bn_str.begin(), bn_str.end());

    BIGNUM* bn = BN_bin2bn(reinterpret_cast<const unsigned char*>(bn_str.c_str()),
                           static_cast<int>(bn_str.size()),
                           nullptr);
    if (!bn) {
        OPERATION_FAIL("BN_bin2bn", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    return bn;
}

BIGNUM* ECCOperator::bnBinaryCharToBn(const std::vector<unsigned char>& bn_bin_vector)
{
    BIGNUM* bn = BN_bin2bn(bn_bin_vector.data(), static_cast<int>(bn_bin_vector.size()), nullptr);
    if (!bn) {
        OPERATION_FAIL("bnBinaryCharToBn", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    return bn;
}

std::string ECCOperator::bnToBinarryString(const BIGNUM* bn)
{
    std::vector<unsigned char> bn_bin_vector(BN_num_bytes(bn));
    if (bn_bin_vector.empty()) {
        OPERATION_FAIL("Failed to allocate vector for BIGNUM", "ECCOperator", __FILE__, __LINE__, "");
        return "";
    }

    if (BN_bn2bin(bn, bn_bin_vector.data()) <= 0) {
        OPERATION_FAIL("BN_bn2bin", "PLeaderVehicle", __FILE__, __LINE__, "");
        return "";
    }
    std::string bn_bin_str(bn_bin_vector.begin(), bn_bin_vector.end());

    return bn_bin_str;
}

std::string ECCOperator::bnTohexString(const BIGNUM* bn)
{
    char* BnHex = BN_bn2hex(bn);
    if (!BnHex) {
        OPERATION_FAIL("BN_bn2hex", "PLeaderVehicle", __FILE__, __LINE__, "");
        return "";
    }

    std::string Bn_Hex_str(BnHex);

    //释放内存
    OPENSSL_free(BnHex);

    return Bn_Hex_str;
}

int ECCOperator::BN_ECKey_Conv_EC_EVPKey(BIGNUM* k_priv,
                                         EC_POINT* k_pub,
                                         EC_GROUP* group,
                                         EVP_PKEY** out_evp_pkey)
{
    if (!k_priv || !k_pub || !group || !out_evp_pkey) {
        std::cerr << "nullptr parameter provided to BN_ECKey_Conv_EC_EVPKey" << std::endl;
        return 0;
    }

    //准备EVP_PKEY_ctx上下文对象
    EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr);

    if (!pctx) {
        handleOpenSSLErrors();

        return 0;
    }

    if (EVP_PKEY_fromdata_init(pctx) <= 0) {
        handleOpenSSLErrors();
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    //提取公钥参数
    size_t k_pub_len = EC_POINT_point2oct(curveAttributes_,
                                          k_pub,
                                          POINT_CONVERSION_UNCOMPRESSED,
                                          nullptr,
                                          0,
                                          ctx_);
    unsigned char* k_pub_c = (unsigned char*) OPENSSL_malloc(k_pub_len);
    if (!k_pub_c) {
        std::cout << "286" << std::endl;
        EVP_PKEY_CTX_free(pctx);
        handleOpenSSLErrors();
        return 0;
    }

    EC_POINT_point2oct(curveAttributes_,
                       k_pub,
                       POINT_CONVERSION_UNCOMPRESSED,
                       k_pub_c,
                       k_pub_len,
                       ctx_);

    OSSL_PARAM_BLD* param_bld;
    OSSL_PARAM* params = nullptr;
    param_bld = OSSL_PARAM_BLD_new();
    if (k_priv != nullptr && param_bld != nullptr
        && OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME, "prime256v1", 0)
        && OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, k_priv)
        && OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY, k_pub_c, k_pub_len)) {
        params = OSSL_PARAM_BLD_to_param(param_bld);
    }

    if (EVP_PKEY_fromdata(pctx, out_evp_pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
        handleOpenSSLErrors();
        if (params != nullptr)
            OPENSSL_free(params);
        if (param_bld != nullptr)
            OSSL_PARAM_BLD_free(param_bld);
        OPENSSL_free(k_pub_c);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    if (params != nullptr)
        OPENSSL_free(params);
    if (param_bld != nullptr)
        OSSL_PARAM_BLD_free(param_bld);
    OPENSSL_free(k_pub_c);
    EVP_PKEY_CTX_free(pctx);
    return 1;
}

int ECCOperator::ECPubKey_Conv_EVPPubKey(EC_POINT* k_pub, EC_GROUP* group, EVP_PKEY** out_evp_pubkey)
{
    if (!k_pub) {
        OPERATION_FAIL("k_pub is nullptr ", "ECCOperator", __FILE__, __LINE__, "");
        return 0;
    }

    if (!group) {
        OPERATION_FAIL("group is nullptr ", "ECCOperator", __FILE__, __LINE__, "");
        return 0;
    }
    //创建EVP_PKEY上下文对象
    EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr);

    if (!pctx) {
        handleOpenSSLErrors();
        return 0;
    }
    //初始化上下文
    if (EVP_PKEY_fromdata_init(pctx) <= 0) {
        handleOpenSSLErrors();
        return 0;
    }
    //将EC_POINT转换二进制转换为8进制
    size_t pubKeyLen = EC_POINT_point2oct(curveAttributes_,
                                          k_pub,
                                          POINT_CONVERSION_UNCOMPRESSED,
                                          nullptr,
                                          0,
                                          ctx_);

    if (pubKeyLen == 0) {
        handleOpenSSLErrors();
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    unsigned char* k_pub_c = (unsigned char*) OPENSSL_malloc(pubKeyLen);
    if (!k_pub_c) {
        EVP_PKEY_CTX_free(pctx);
        handleOpenSSLErrors();
        return 0;
    }

    EC_POINT_point2oct(curveAttributes_,
                       k_pub,
                       POINT_CONVERSION_UNCOMPRESSED,
                       k_pub_c,
                       pubKeyLen,
                       ctx_);

    //设置OSSL_PARAM params参数
    OSSL_PARAM params[]
        = {OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*) "prime256v1", 0),
           OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, k_pub_c, pubKeyLen),
           OSSL_PARAM_construct_end()};

    if (EVP_PKEY_fromdata(pctx, out_evp_pubkey, EVP_PKEY_KEYPAIR, params) <= 0) {
        handleOpenSSLErrors();
        OPENSSL_free(k_pub_c);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    OPENSSL_free(k_pub_c);
    EVP_PKEY_CTX_free(pctx);
    return 1;
}

/**
 * @brief 这个函数的作用就是将BIGNUM类型的私钥转换为EVP_PKEY类型的私钥。主要使用EVP接口和OSSL_PARAM参数来处理密码操作。
 * @param k_pri
 * @param group
 * @param out_evp_prikey
 * @return
 */
int ECCOperator::BN_Convert_EVPPriKey(BIGNUM* k_pri, EC_GROUP* group, EVP_PKEY** out_evp_prikey)
{
    if (!k_pri || !out_evp_prikey) {
        std::cerr << "Invalid input: k_pri or out_evp_prikey is null." << std::endl;
        return -1;
    }

    // 创建 EVP_PKEY 上下文
    EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr);
    if (!pctx) {
        handleOpenSSLErrors();
        return -1;
    }

    // 初始化上下文
    if (EVP_PKEY_fromdata_init(pctx) <= 0) {
        handleOpenSSLErrors();
        EVP_PKEY_CTX_free(pctx);
        return -1;
    }

    // 创建 OSSL_PARAM_BLD 参数构建器
    OSSL_PARAM_BLD* param_bld = OSSL_PARAM_BLD_new();
    if (!param_bld) {
        std::cerr << "Failed to create OSSL_PARAM_BLD!" << std::endl;
        EVP_PKEY_CTX_free(pctx);
        return -1;
    }

    // 设置曲线名称和私钥
    if (!OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_PKEY_PARAM_GROUP_NAME, "prime256v1", 0)
        || !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, k_pri)) {
        std::cerr << "Failed to push parameters to OSSL_PARAM_BLD!" << std::endl;
        OSSL_PARAM_BLD_free(param_bld);
        EVP_PKEY_CTX_free(pctx);
        return -1;
    }

    // 构建 OSSL_PARAM 参数
    OSSL_PARAM* params = OSSL_PARAM_BLD_to_param(param_bld);
    if (!params) {
        std::cerr << "Failed to create OSSL_PARAM from OSSL_PARAM_BLD!" << std::endl;
        OSSL_PARAM_BLD_free(param_bld);
        EVP_PKEY_CTX_free(pctx);
        return -1;
    }

    // 使用参数生成 EVP_PKEY
    if (EVP_PKEY_fromdata(pctx, out_evp_prikey, EVP_PKEY_KEYPAIR, params) <= 0) {
        std::cerr << "Failed to create EVP_PKEY from BIGNUM!" << std::endl;
        handleOpenSSLErrors();
        OSSL_PARAM_free(params);
        OSSL_PARAM_BLD_free(param_bld);
        EVP_PKEY_CTX_free(pctx);
        return -1;
    }

    // 释放资源
    OSSL_PARAM_free(params);
    OSSL_PARAM_BLD_free(param_bld);
    EVP_PKEY_CTX_free(pctx);

    return 1;
}

int ECCOperator::deriveSymmetricKey(const EC_GROUP* group,
                                    const EC_POINT* pub_key,
                                    BIGNUM* priv_key,
                                    const unsigned char* salt,
                                    unsigned char* out_key)
{
    // const EC_GROUP *group  表示椭圆曲线群；const EC_POINT *pub_key 表示接收者的公钥； BIGNUM *priv_key
    // 表示发送者的私钥 unsigned char *out_key 表示输出的对称密钥 size_t out_len：表示对称密钥的长度。

    // 创建一个新的 EC_POINT 来存储计算结果

    if (!priv_key) {
        std::cerr << "ERROR: priv_key is nullptr" << std::endl;
        return 0;
    }

    EC_POINT* shared_point = EC_POINT_new(group);
    if (!shared_point) {
        perror("shared_point");
        return 0;
    }
    // 计算共享秘密
    if (!EC_POINT_mul(group, shared_point, nullptr, pub_key, priv_key, ctx_)) {
        perror("EC_POINT_mul");
        EC_POINT_free(shared_point);
        return 0;
    }
    // 将共享点转换为字节序列
    unsigned char* shared_secret = nullptr;
    int secret_len = EC_POINT_point2buf(group,
                                        shared_point,
                                        POINT_CONVERSION_UNCOMPRESSED,
                                        &shared_secret,
                                        ctx_);
    if (secret_len <= 0) {
        perror("EC_POINT_point2buf");
        return 0;
    }

    //对共享秘密进行哈希处理以生成对称密钥
    // SHA256( shared_secret, secret_len, out_key );
    int ret = PKCS5_PBKDF2_HMAC((const char*) shared_secret,
                                secret_len,
                                salt,
                                16,
                                10000,
                                EVP_sha256(),
                                32,
                                out_key);
    if (!ret) {
        handleOpenSSLErrors();
        EC_POINT_free(shared_point);
        OPENSSL_free(shared_secret);
        return 0;
    }
    EC_POINT_free(shared_point);
    OPENSSL_free(shared_secret);
    // std::cout << "会话密钥协商完毕" << std::endl;
    return 1;
}

std::vector<unsigned char> ECCOperator::EVP_PKEY_PublicKey_Convert_TO_DER(EVP_PKEY* pkey)
{
    if (!pkey) {
        std::cerr << "EVP_PKEY is null!" << CURRENT_TIME << std::endl;
        return {};
    }

    unsigned char* pubkey_DER = nullptr;
    int der_len = i2d_PUBKEY(pkey, &pubkey_DER);
    if (der_len <= 0) {
        std::cerr << "Failed to convert public key to DER format!" << CURRENT_TIME << std::endl;
        return {};
    }

    std::vector<unsigned char> pubkey_der_vector(pubkey_DER, pubkey_DER + der_len);
    OPERATION_SUCCESS("converted public key to DER format", "ECCOperator", "");
    OPENSSL_free(pubkey_DER);
    return pubkey_der_vector;
}

std::shared_ptr<EC_POINT> ECCOperator::ec_point_mul(const std::shared_ptr<BIGNUM>& bn,
                                                    const std::shared_ptr<EC_POINT>& ec_point)
{
    std::shared_ptr<EC_POINT> ec_point_ptr(EC_POINT_new(curveAttributes_), ECPointDeleter);
    if (!ec_point_ptr) {
        OPERATION_FAIL("EC_POINT_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    if (!EC_POINT_mul(curveAttributes_, ec_point_ptr.get(), nullptr, ec_point.get(), bn.get(), ctx_)) {
        OPERATION_FAIL("EC_POINT_mul", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    return ec_point_ptr;
}

std::shared_ptr<EC_POINT> ECCOperator::ec_point_mul(const std::shared_ptr<BIGNUM>& bn)
{
    std::shared_ptr<EC_POINT> ec_point_ptr(EC_POINT_new(curveAttributes_), ECPointDeleter);
    if (!ec_point_ptr) {
        OPERATION_FAIL("EC_POINT_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    if (!EC_POINT_mul(curveAttributes_, ec_point_ptr.get(), bn.get(), nullptr, nullptr, ctx_)) {
        OPERATION_FAIL("EC_POINT_mul", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    return ec_point_ptr;
}

std::shared_ptr<EC_POINT> ECCOperator::ec_point_add(const std::shared_ptr<EC_POINT>& a,
                                                    const std::shared_ptr<EC_POINT>& b)
{
    std::shared_ptr<EC_POINT> ecpoint_add_result(EC_POINT_new(curveAttributes_), ECPointDeleter);
    if (!ecpoint_add_result) {
        OPERATION_FAIL("EC_POINT_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    if (!EC_POINT_add(curveAttributes_, ecpoint_add_result.get(), a.get(), b.get(), ctx_)) {
        OPERATION_FAIL("EC_POINT_add", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    return ecpoint_add_result;
}

std::shared_ptr<BIGNUM> ECCOperator::bn_add(const std::shared_ptr<BIGNUM>& a,
                                            const std::shared_ptr<BIGNUM>& b)
{
    std::shared_ptr<BIGNUM> result(BN_new(), BnDeleter);
    if (!result) {
        OPERATION_FAIL("BN_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    if (!BN_add(result.get(), a.get(), b.get())) {
        OPERATION_FAIL("BN_add", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    return result;
}

std::shared_ptr<BIGNUM> ECCOperator::bn_mul(const std::shared_ptr<BIGNUM>& a,
                                            const std::shared_ptr<BIGNUM>& b)
{
    std::shared_ptr<BIGNUM> result(BN_new(), BnDeleter);
    if (!result) {
        OPERATION_FAIL("BN_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    if (!BN_mul(result.get(), a.get(), b.get(), ctx_)) {
        OPERATION_FAIL("BN_mul", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    return result;
}

std::shared_ptr<BIGNUM> ECCOperator::bn_nnmod(const std::shared_ptr<BIGNUM>& a)
{
    std::shared_ptr<BIGNUM> result(BN_new(), BnDeleter);
    if (!result) {
        OPERATION_FAIL("BN_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    if (!BN_nnmod(result.get(), a.get(), n_, ctx_)) {
        OPERATION_FAIL("BN_nnmod", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    return result;
}

std::vector<unsigned char> ECCOperator::calculateHMAC(const std::string& key,
                                                      const std::string& message)
{
    unsigned char* result = nullptr;
    unsigned int result_len = 0;
    result = HMAC(EVP_sha256(),
                  key.data(),
                  key.size(),
                  reinterpret_cast<const unsigned char*>(message.data()),
                  message.size(),
                  nullptr,
                  &result_len);
    return std::vector<unsigned char>(result, result + result_len);
}

std::vector<unsigned char> ECCOperator::calculateHMAC(const std::vector<unsigned char>& key_vector,
                                                      const std::string& message)
{
    unsigned char* result = nullptr;
    unsigned int result_len = 0;
    result = HMAC(EVP_sha256(),
                  key_vector.data(),
                  static_cast<int>(key_vector.size()),
                  reinterpret_cast<const unsigned char*>(message.data()),
                  message.size(),
                  nullptr,
                  &result_len);
    return std::vector<unsigned char>(result, result + result_len);
}

bool ECCOperator::verifyHmac(const std::string& hmac1, const std::string& hmac2)
{
    if (hmac1.size() != hmac2.size()) {
        OPERATION_FAIL("verifyHmac: ",
                       "ECCOperator",
                       __FILE__,
                       __LINE__,
                       "HMAC values do not match. Lengths are different.");
        return false;
    }

    if (std::equal(hmac1.begin(), hmac1.end(), hmac2.begin())) {
        OPERATION_SUCCESS("verifyHmac", "ECCOperator", "");
        return true;
    } else {
        std::cout << " hmac1: "
                  << base64_encode(reinterpret_cast<const unsigned char*>(hmac1.c_str()),
                                   hmac1.size())
                  << std::endl;
        std::cout << " hmac2: "
                  << base64_encode(reinterpret_cast<const unsigned char*>(hmac2.c_str()),
                                   hmac2.size())
                  << std::endl;
        OPERATION_FAIL("verifyHmac ", "ECCOperator", __FILE__, __LINE__, "");
        return false;
    }
}

std::string ECCOperator::DERConvertTOPEM(const unsigned char* der_data, size_t der_len)
{
    EVP_PKEY* public_key = DER_Pubkey_Convert_TO_EVP_PKEY(der_data, der_len);
    if (!public_key) {
        OPERATION_FAIL("DER_Pubkey_Convert_TO_EVP_PKEY", "ECCOperator", __FILE__, __LINE__, "");
        return "";
    }

    std::string pubKey_pem = EVP_PKEY_PublicKeyToPem(public_key);
    return pubKey_pem;
}

EVP_PKEY* ECCOperator::DER_Pubkey_Convert_TO_EVP_PKEY(const unsigned char* der_data, size_t der_len)
{
    if (!der_data) {
        OPERATION_FAIL("der_data is nullprt", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    EVP_PKEY* evp_key = d2i_PUBKEY(nullptr, &der_data, static_cast<long>(der_len));
    if (!evp_key) {
        OPERATION_FAIL("d2i_PUBKEY", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    return evp_key;
}

//将EVP_PKEY提取成BIGNUM和EC_POINT类型的函数
bool ECCOperator::extract_Pub_Priv_Frome_EVP_PKEY(EVP_PKEY* pkey,
                                                  BIGNUM** priv,
                                                  EC_POINT** pub,
                                                  Model model)
{
    if (!pkey) {
        std::cout << "pkey is nullptr" << std::endl;
        return false;
    }

    switch (model) {
    case ONLYGETPRIKEY: {
        if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
            std::cout << "Error: Failed to get private key" << std::endl;
            return false;
        }
        // std::cout << "Private key extracted successfully" << std::endl;
        break;
    }

    case ONLYGETPUBKEY: {
        size_t pub_len = 0;
        if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &pub_len)
            != 1) {
            std::cout << "Error: Failed to get public key length" << std::endl;
            return false;
        }
        unsigned char* pubkey_oct = (unsigned char*) OPENSSL_malloc(pub_len);
        if (!pubkey_oct) {
            std::cout << "Error: Failed to openssl_malloc" << std::endl;
            return false;
        }

        if (EVP_PKEY_get_octet_string_param(pkey,
                                            OSSL_PKEY_PARAM_PUB_KEY,
                                            pubkey_oct,
                                            pub_len,
                                            &pub_len)
            != 1) {
            std::cout << "Error: Failed to get public key OCT" << std::endl;
            return false;
        }
        EC_POINT* pubkey = EC_POINT_new(getGroup());
        if (!pubkey) {
            std::cout << "Error: Failed to create EC_POINT" << std::endl;
            OPENSSL_free(pubkey_oct);
            return false;
        }
        //然后将字符串转换为EC_POINT
        if (EC_POINT_oct2point(getGroup(), pubkey, pubkey_oct, pub_len, ctx_) != 1) {
            std::cout << "Error: EC_POINT_oct2point" << std::endl;
            OPENSSL_free(pubkey_oct);
            EC_POINT_free(pubkey);
            return false;
        }
        *pub = pubkey;
        OPENSSL_free(pubkey_oct);
        // std::cout << "Public key extracted successfully" << std::endl;
        break;
    }

    case GETBOTH: {
        //处理私钥这部分
        if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
            std::cout << "Error: Failed to get private key" << std::endl;
            return false;
        }
        // std::cout << "Private key extracted successfully" << std::endl;

        //处理公钥这部分
        size_t pub_len = 0;
        if (EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &pub_len)
            != 1) {
            std::cout << "Error: Failed to get public key length" << std::endl;
            return false;
        }
        unsigned char* pubkey_oct = (unsigned char*) OPENSSL_malloc(pub_len);
        if (!pubkey_oct) {
            std::cout << "Error: Failed to openssl_malloc" << std::endl;
            return false;
        }

        if (EVP_PKEY_get_octet_string_param(pkey,
                                            OSSL_PKEY_PARAM_PUB_KEY,
                                            pubkey_oct,
                                            pub_len,
                                            &pub_len)
            != 1) {
            std::cout << "Error: Failed to get public key OCT" << std::endl;
            return false;
        }
        EC_POINT* pubkey = EC_POINT_new(getGroup());
        if (!pubkey) {
            std::cout << "Error: Failed to create EC_POINT" << std::endl;
            OPENSSL_free(pubkey_oct);
            return false;
        }
        //然后将字符串转换为EC_POINT
        if (EC_POINT_oct2point(getGroup(), pubkey, pubkey_oct, pub_len, ctx_) != 1) {
            std::cout << "Error: EC_POINT_oct2point" << std::endl;
            OPENSSL_free(pubkey_oct);
            EC_POINT_free(pubkey);
            return false;
        }
        *pub = pubkey;
        OPENSSL_free(pubkey_oct);
        // std::cout << "Public key extracted successfully" << std::endl;
        break;
    }
    default: {
        std::cerr << "Error: Unsupported key extraction model" << std::endl;
        return false;
    }
    }
    return true;
}

std::string ECCOperator::generateESDSASignature(EVP_PKEY* priKey, const std::string rawData)
{
    //签名函数的函数原型EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char
    //*tbs,
    // size_t tbslen)

    //创建EVP_MD_CTX *ctx
    EVP_MD_CTX* mctx = EVP_MD_CTX_new();
    if (!mctx) {
        std::cout << "EVP_MD_CTX_new() 创建ctx失败" << std::endl;
        return "";
    }

    //使用EVP_sha256()函数来生成消息的摘要这个摘要应该能够代表原始消息的独一无二的指纹
    //摘要初始化

    if (EVP_DigestSignInit(mctx, nullptr, EVP_sha256(), nullptr, priKey) <= 0) {
        std::cerr << "签名操作初始化失败" << std::endl;
        EVP_MD_CTX_free(mctx);
        return "";
    }

    size_t sign_len = 0;
    //将字符串转换为const unsigned char *
    size_t rawDataLength = rawData.size();

    //创建字符数组
    unsigned char rawDataArray[rawDataLength];
    memcpy(rawDataArray, rawData.c_str(), rawDataLength);

    //获取签名长度
    EVP_DigestSign(mctx, nullptr, &sign_len, rawDataArray, rawDataLength);

    //进行签名,

    unsigned char sign[sign_len];

    if (EVP_DigestSign(mctx, sign, &sign_len, rawDataArray, rawDataLength) <= 0) {
        std::cerr << "产生签名失败" << std::endl;
        EVP_MD_CTX_free(mctx);
        return "";
    }

    //释放上下文
    EVP_MD_CTX_free(mctx);

    //构造签名的字符串
    std::string signDataStr(reinterpret_cast<const char*>(sign), sign_len);
    return signDataStr;
}

bool ECCOperator::verifyEDSAsignature(EVP_PKEY* pubkey,
                                      const std::string& rawData,
                                      const std::string& signData)
{
    if (pubkey == nullptr) {
        std::cerr << "错误：公钥为空" << std::endl;
        return false;
    }

    EVP_MD_CTX* mctx = EVP_MD_CTX_new();
    if (!mctx) {
        std::cerr << "错误：创建EVP_MD_CTX失败" << std::endl;
        return false;
    }

    if (EVP_sha256() == nullptr) {
        std::cerr << "EVP_sha256() 返回 nullptr" << std::endl;
    }

    if (EVP_DigestVerifyInit(mctx, nullptr, EVP_sha256(), nullptr, pubkey) <= 0) {
        std::cerr << "错误：签名验证初始化失败" << std::endl;
        EVP_MD_CTX_free(mctx);
        return false;
    }

    const unsigned char* rawData_c = reinterpret_cast<const unsigned char*>(rawData.c_str());
    size_t rawDataLength = rawData.size();

    const unsigned char* signData_c = reinterpret_cast<const unsigned char*>(signData.c_str());
    size_t signLen = signData.size();

    if (rawDataLength == 0 || signLen == 0) {
        std::cerr << "错误：数据长度为零" << std::endl;
        EVP_MD_CTX_free(mctx);
        return false;
    }

    int ret = EVP_DigestVerify(mctx, signData_c, signLen, rawData_c, rawDataLength);
    if (ret == 1) {
        // std::cout << "签名验证通过" << std::endl;
        EVP_MD_CTX_free(mctx);
        return true;
    } else if (ret == 0) {
        std::cerr << "签名验证不通过，签名不一致" << std::endl;
        EVP_MD_CTX_free(mctx);
        return false;
    } else {
        // std
        std::cerr << "EVP_DigestVerify函数错误" << std::endl;
        EVP_MD_CTX_free(mctx);
        unsigned long err_code = ERR_get_error();
        if (err_code != 0) {
            char err_msg[256];
            ERR_error_string_n(err_code, err_msg, sizeof(err_msg));
            fprintf(stderr, "错误信息: %s\n", err_msg);
        }
        return false;
    }
}

size_t ECCOperator::computeSessionKey(EVP_PKEY* myPriKey,
                                      EVP_PKEY* peerPubKey,
                                      unsigned char** sessionKey)
{
    EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new(myPriKey, nullptr);
    if (!pctx) {
        // ERR_print_errors_fp(stderr);
        return 0;
    }

    //初始化密钥派生
    if (EVP_PKEY_derive_init(pctx) <= 0) {
        // ERR_print_errors_fp(stderr);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }
    // std::cout << "1111" << std::endl;
    //设置对方的公钥
    if (EVP_PKEY_derive_set_peer(pctx, peerPubKey) <= 0) {
        // ERR_print_errors_fp(stderr);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    size_t keyLen = 0;
    //确定派生密钥的长度
    if (EVP_PKEY_derive(pctx, nullptr, &keyLen) <= 0) {
        // ERR_print_errors_fp(stderr);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    //创建密钥接收缓冲区
    unsigned char* sessKey = (unsigned char*) OPENSSL_malloc(keyLen);

    if (!sessKey) {
        // ERR_print_errors_fp(stderr);
        EVP_PKEY_CTX_free(pctx);
        return 0;
    }

    //派生密钥
    if (EVP_PKEY_derive(pctx, sessKey, &keyLen) <= 0) {
        // ERR_print_errors_fp(stderr);
        EVP_PKEY_CTX_free(pctx);
        OPENSSL_free(sessKey);
        return 0;
    }

    EVP_PKEY_CTX_free(pctx);
    *sessionKey = sessKey;
    return keyLen;
}

std::vector<unsigned char> ECCOperator::SHA256(const std::vector<unsigned char>& data)
{
    uint16_t dataSize = data.size();
    const uint8_t hashSize = EVP_MD_size(EVP_sha256());
    std::vector<unsigned char> hash(hashSize);
    uint32_t hashLen = 0;

    if (!EVP_Digest(data.data(), dataSize, hash.data(), &hashLen, EVP_sha256(), nullptr)) {
        std::cerr << "Failed to generate hash" << CURRENT_TIME << std::endl;
        return {};
    }

    return hash;
}

void ECCOperator::saveECPointToFile(const EC_POINT* point, const std::string& fileName)
{
    char* point_hex = EC_POINT_point2hex(curveAttributes_,
                                         point,
                                         POINT_CONVERSION_UNCOMPRESSED,
                                         ctx_);
    if (point_hex) {
        std::string point_hex_str(point_hex);

        OPENSSL_free(point_hex);
        std::ofstream outFile(fileName);
        outFile << point_hex_str;
        outFile.close();
        // OPERATION_SUCCESS("save ECPoint To File"+ fileName, "ECCOperator", point_hex_str);
    }
}

void ECCOperator::saveBNToFile(const BIGNUM* BN, const std::string& fileName)
{
    char* bn_hex = BN_bn2hex(BN);
    if (bn_hex) {
        std::string bn_hex_str(bn_hex);
        OPENSSL_free(bn_hex);
        std::ofstream outFile(fileName);
        outFile << bn_hex_str;
        outFile.close();
        // OPERATION_SUCCESS("save BIGNUM To File" + fileName, "ECCOperator", bn_hex_str);
    }
}

void ECCOperator::saveBNBinaryToFile(const BIGNUM* BN, const std::string& fileName)
{
    std::string bnBinStr = bnToBinarryString(BN);
    if (bnBinStr.empty()) {
        OPERATION_FAIL("bnBinStr is empty", "Initialization", __FILE__, __LINE__, "");
        return;
    }
    std::ofstream outputFile(fileName);
    outputFile << bnBinStr;
    outputFile.close();

    // std::string hexBnstr = bnTohexString(BN);
    // OPERATION_SUCCESS("save BIGNUM To File" + fileName, "ECCOperator", hexBnstr);
}

void ECCOperator::saveECPOINTBinaryToFile(const EC_POINT* point, const std::string& fileName)
{
    std::string bnPointStr = ecPointToBinaryString(point);
    if (bnPointStr.empty()) {
        OPERATION_FAIL("bnBinStr is empty", "Initialization", __FILE__, __LINE__, "");
        return;
    }
    std::ofstream outputFile(fileName);
    outputFile << bnPointStr;
    outputFile.close();
    // std::string ecpoint_hex_str = EC_POINT_To_String(point);
    // OPERATION_SUCCESS("save ECPOINT To File" + fileName, "ECCOperator", ecpoint_hex_str);
}

BIGNUM* ECCOperator::readBNFromFile(const std::string& fileName)
{
    if (!std::filesystem::exists(fileName)) {
        std::cerr << "File does not exist: " << fileName << std::endl;
        return nullptr;
    }
    std::ifstream inputFile(fileName, std::ios_base::in);
    if (!inputFile.is_open()) {
        OPERATION_FAIL("readBNFromFile", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    std::string BN_str((std::istreambuf_iterator<char>(inputFile)),
                       std::istreambuf_iterator<char>());
    inputFile.close();
    //std::cout<<" BN_str: "<<BN_str<<std::endl;
    BIGNUM* bn = nullptr;
    if (!BN_hex2bn(&bn, BN_str.c_str())) {
        OPERATION_FAIL("BN_hex2bn", "PLeaderVehicle", __FILE__, __LINE__, "");
        return nullptr;
    }
    return bn;
}

EC_POINT* ECCOperator::readECPOINTFromFile(const std::string& fileName)
{
    if (!std::filesystem::exists(fileName)) {
        std::cerr << "File does not exist: " << fileName << std::endl;
        return nullptr;
    }

    std::ifstream inputFile(fileName, std::ios_base::in);
    if (!inputFile.is_open()) {
        OPERATION_FAIL("readBNFromFile", "PLeaderVehicle", __FILE__, __LINE__, "");
        return nullptr;
    }

    std::string EC_POINT_str((std::istreambuf_iterator<char>(inputFile)),
                             std::istreambuf_iterator<char>());
    inputFile.close();
    //std::cout<<" EC_POINT_str: "<<EC_POINT_str<<std::endl;
    EC_POINT* point = EC_POINT_hex2point(curveAttributes_, EC_POINT_str.c_str(), nullptr, ctx_);
    if (!point) {
        OPERATION_FAIL("EC_POINT_hex2point", "PLeaderVehicle", __FILE__, __LINE__, "");
        return nullptr;
    }

    return point;
}

std::string ECCOperator::EVP_PKEY_PublicKeyToPem(EVP_PKEY* publicKey)
{
    BIO* bio = BIO_new(BIO_s_mem());
    if (!bio) {
        std::cerr << "BIO_new failed to create BIO! " << CURRENT_TIME << std::endl;
        return "";
    }

    if (!PEM_write_bio_PUBKEY(bio, publicKey)) {
        std::cerr << "Failed to write public key to memory!" << CURRENT_TIME << std::endl;
        return "";
    }

    //写入完毕后，我们就需要冲内存中获取这些数据
    char* buffer = nullptr;
    int length = BIO_get_mem_data(bio, &buffer);
    if (length <= 0 || !buffer) {
        std::cerr << "Failed to get data from memory BIO!" << CURRENT_TIME << std::endl;
        BIO_free(bio);
        return "";
    }
    // 显式复制缓冲区数据到 std::string
    std::string pemKey(buffer, length);
    BIO_free(bio);
    return pemKey;
}

EVP_PKEY* ECCOperator::PUBKEY_PEM_To_EVP_PKEY(const std::string& pubkeyPem)
{
    BIO* bio = BIO_new_mem_buf(pubkeyPem.c_str(), static_cast<int>(pubkeyPem.size()));
    if (!bio) {
        std::cerr << " BIO_new_mem_buf is failed! " << CURRENT_TIME << std::endl;
        return nullptr;
    }

    EVP_PKEY* PUBKEY = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
    if (!PUBKEY) {
        std::cerr << "PEM_read_bio_PUBKEY failed to extract the public key! " << CURRENT_TIME
                  << std::endl;
        BIO_free(bio);
        return nullptr;
    }

    BIO_free(bio);
    return PUBKEY;
}

bool ECCOperator::arePointsEqual(const EC_POINT* point1, const EC_POINT* point2)
{
    if (!point1 || !point2) {
        OPERATION_FAIL(" point1/point2 is nullptr ", "ECCOperator", __FILE__, __LINE__, "");
        return false;
    }
    int cmp_result = EC_POINT_cmp(curveAttributes_, point1, point2, ctx_);

    if (cmp_result != 0)
        return false;
    return true;
}

BIGNUM* ECCOperator::EVPPriKey_Convert_BN(EVP_PKEY* pkey)
{
    if (!pkey) {
        OPERATION_FAIL(" pkey is nullptr ", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    // 检查密钥类型是否为 ECC
    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
        OPERATION_FAIL("pkey Not an ECC key ", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    BIGNUM* bn_priKey = nullptr;
    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn_priKey)) {
        OPERATION_FAIL("Failed to extract private key using EVP_PKEY_get_bn_param. ",
                       "ECCOperator",
                       __FILE__,
                       __LINE__,
                       "");
        handleOpenSSLErrors();
        return nullptr;
    }

    // char* hex = BN_bn2hex(bn_priKey);
    // std::cout << "Private Key: " << hex << std::endl;
    // OPENSSL_free(hex);

    return bn_priKey;
}

EC_POINT* ECCOperator::EVP_PKEY_PubKey_Convert_EC(EVP_PKEY* pkey)
{
    if (!pkey) {
        OPERATION_FAIL(" pkey is nullptr ", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    // 检查密钥类型是否为 ECC
    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
        OPERATION_FAIL("pkey Not an ECC key ", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    size_t key_size = 0;
    if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &key_size)) {
        OPERATION_FAIL(" EVP_PKEY_get_octet_string_param", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }

    std::vector<unsigned char> pubKey_buf(key_size);
    if (!EVP_PKEY_get_octet_string_param(pkey,
                                         OSSL_PKEY_PARAM_PUB_KEY,
                                         pubKey_buf.data(),
                                         key_size,
                                         &key_size)) {
        OPERATION_FAIL(" EVP_PKEY_get_octet_string_param", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    EC_POINT* ecPoint = EC_POINT_new(curveAttributes_);
    if (!ecPoint) {
        OPERATION_FAIL(" EC_POINT_new", "ECCOperator", __FILE__, __LINE__, "");
        return nullptr;
    }
    //从二进制中还原中EC_POINT
    if (!EC_POINT_oct2point(curveAttributes_, ecPoint, pubKey_buf.data(), pubKey_buf.size(), ctx_)) {
        EC_POINT_free(ecPoint);
        return nullptr;
    }

    return ecPoint;
}
